import java.util.SortedMap;
import java.util.TreeMap;


public class AudioSearcher {
	
	public SortedMap<Double, AudioFeature> SearchBasedOnDistance(AudioFeature searchFeature, AudioFeature [] featureDic  )
	{
		SortedMap<Double, AudioFeature> sm = new TreeMap<Double, AudioFeature>();
		for(int i=0; i < featureDic.length; i++)
		{
			AudioFeature cmpFeature = featureDic[i];
			double distance = CalculateMinDistance(searchFeature, featureDic[i]);
			sm.put(distance, cmpFeature);
		}
		return sm;
	}
	
	public double CalculateMinDistance(AudioFeature srcFeature, AudioFeature destFeature)
	{
		double distance = Double.MAX_VALUE;
		AudioFeature standardFeature = null;
		AudioFeature cmpFeature = null;
		if(srcFeature.getFeatures().size()< destFeature.getFeatures().size())
		{
			 standardFeature = srcFeature;
			 cmpFeature = destFeature;
		}
		else 
		{
			 standardFeature = destFeature;
			 cmpFeature = srcFeature;
		}
		int offset = 0; 
		int offsetLength = cmpFeature.getFeatures().size() - standardFeature.getFeatures().size();
		AudioFeature wndFeature = new AudioFeature();
		for(int i =offset; i <= offsetLength; i++)
		{
			ExtractFeature(cmpFeature, wndFeature, offset, standardFeature.getFeatures().size());
			double curDistance = CalculateDistance(standardFeature, wndFeature);
			if(distance > curDistance)
			{
				distance = curDistance;
			}
		}
		return distance;
	}
	
	public void ExtractFeature(AudioFeature fullFeature, AudioFeature windowFeature, int offset, int windowSize)
	{
		windowFeature.getFeatures().clear();
		int fullFeatureLength = fullFeature.getFeatures().size();
		int length =  fullFeatureLength > windowSize ? windowSize : fullFeatureLength;
		for(int i=0; i < length; i++)
		{
			AudioSection section = fullFeature.getFeatures().get(offset+i);
			windowFeature.getFeatures().add(section);
		}
	}
	
	public double CalculateDistance(AudioFeature srcFeature, AudioFeature destFeature)
	{
		double distance = 0;
		int length = Math.min(srcFeature.getFeatures().size(), srcFeature.getFeatures().size());
		int step = length / 100;
		for(int i =0; i < length; i+=step)
		{
			AudioSection srcSection =  srcFeature.getFeatures().get(i);
			AudioSection destSection =  destFeature.getFeatures().get(i);
			for(int j=0; j < srcSection.values.length; j++)
			{
				double result = (srcSection.values[j]-destSection.values[j]);
				distance += result * result;
			}
		}
		distance = Math.sqrt(distance);
		return distance;
	}
	
	public double GetAVGDistance(AudioFeature srcFeature, AudioFeature destFeature, double distance)
	{
		double result = 0;
		int length = Math.min(srcFeature.getFeatures().size(), srcFeature.getFeatures().size());
		return result / length;
	}
	

}
